#include <vector>


#include "CImg.h"
using namespace cimg_library;

extern CImg<unsigned char> img_rgb;
extern CImg<unsigned char>* img_bg;
extern int Dx, Dy;

extern std::vector<int> clr_picked;
extern std::vector<int> loc_picked;
extern std::vector<std::vector<double>> gkernel;
extern int kernel_radius;


void app_colorpicker()
{
	const int R = kernel_radius;
	const unsigned char white[] = {255,255,255}, black[]={0,0,0};
	CImgDisplay disp;
	CImg<unsigned char> canvas, marker;
	CImg<int> picked;
	
	std::vector<std::pair<int,int>> loc;

	marker.assign(Dx,Dy,1,3,0);
	picked.assign(Dx,Dy,1,1,0);

	canvas.assign(*img_bg);
	canvas.display(disp);
	disp.set_title("Color picker...: a to pick a color");

	bool clicked = true;
	volatile unsigned int btt = 0;
	int mx=0, my=0, px=0, py=0, mouse_x=0, mouse_y=0, prev_x=0, prev_y=0;
	while (!disp.is_closed()) {
		disp.wait();

		if (disp.key()) {
			switch (disp.key())
			{
			case cimg::keyA:
				clicked = false;
				break;
			default:
				break;
			}
			disp.set_key();
		}

		if (disp.mouse_x()>=0 && disp.mouse_y()>=0) {
			mx = disp.mouse_x();
			my = disp.mouse_y();
			mouse_x = mx * Dx/disp.width();
			mouse_y = my * Dy/disp.height();

			btt = disp.button();

			if (btt == 1 && !clicked) {
				const int R = 10;
				int x0 = (mouse_x-R < 0) ? 0: mouse_x-R;
				int y0 = (mouse_y-R < 0) ? 0: mouse_y-R;
				int x1 = (mouse_x+R > Dx-1) ? Dx-1: mouse_x+R;
				int y1 = (mouse_y+R > Dy-1) ? Dy-1: mouse_y+R;

				marker.draw_rectangle(x0,y0,x1,y1, white);
				picked.draw_rectangle(x0,y0,x1,y1, white);

				loc.push_back(std::pair<int,int>(mouse_x,mouse_y));

				clicked = true;
			}
			
			if (btt == 2 && loc.size() > 0) {
				double min_dxy = DBL_MAX;
				int min_i = -1;
				for (unsigned int i=0; i<loc.size(); i++) {
					double dx = mouse_x - loc[i].first;
					double dy = mouse_y - loc[i].second;
					double dxy = std::sqrt(dx*dx + dy*dy);
					if (dxy < min_dxy) {
						min_dxy = dxy;
						min_i = i;
					}
				}

				if (min_i != -1) {
					
					int x0 = (loc[min_i].first  - R < 0) ? 0: loc[min_i].first - R;
					int y0 = (loc[min_i].second - R < 0) ? 0: loc[min_i].second - R;
					int x1 = (loc[min_i].first  + R > Dx-1) ? Dx-1: loc[min_i].first + R;
					int y1 = (loc[min_i].second + R > Dy-1) ? Dy-1: loc[min_i].second + R;

					marker.draw_rectangle(x0,y0,x1,y1, black);
					picked.draw_rectangle(x0,y0,x1,y1, black);

					loc.erase(loc.begin() + min_i);
				}
			}

			prev_x = mouse_x; 
			prev_y = mouse_y;
			px = mx;
			py = my;

			canvas.assign(*img_bg);
			cimg_forXY(picked,x,y) {
				if (picked(x,y) == 0) continue;
				for (int c=0; c<3; c++)
					canvas(x,y,c) = canvas(x,y,c)*0.2 + marker(x,y,c)*0.8;
			}
			canvas.display(disp);
		}
	}

	
	if (loc.size() > 0 ) {
		clr_picked.clear();
		loc_picked.clear();

		for (unsigned int i=0; i<loc.size(); i++) {
			int x0 = loc[i].first  - R;
			int y0 = loc[i].second - R;
			int x1 = loc[i].first  + R;
			int y1 = loc[i].second + R;

			double Red=0.0, Green=0.0, Blue=0.0;
			int gx=0, gy=0;
			for (int y=y0; y<=y1; y++, gy++) {
				for (int x=x0; x<=x1; x++, gx++) {
					if (x0>=0 && x1<Dx && y0>=0 && y1< Dy){
						Red   += (double)img_rgb(x,y,0,0) * gkernel[gy][gx];
						Green += (double)img_rgb(x,y,0,1) * gkernel[gy][gx];
						Blue  += (double)img_rgb(x,y,0,2) * gkernel[gy][gx];
					}
				}
				gx = 0;
			}

			Red = (Red < 0.0) ? 0.0: Red;
			Red = (Red >= 255.0) ? 255.0: Red;
			Green = (Green < 0.0) ? 0.0: Green;
			Green = (Green >= 255.0) ? 255.0: Green;
			Blue = (Blue < 0.0) ? 0.0: Blue;
			Blue = (Blue >= 255.0) ? 255.0: Blue;

			clr_picked.push_back( (int)Red );
			clr_picked.push_back( (int)Blue );
			clr_picked.push_back( (int)Green );

			loc_picked.push_back( loc[i].first );
			loc_picked.push_back( loc[i].second );
		}

	}

}